
#include "Application.h"
#include "../Logger.h"
#include "SDLException.h"
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>

namespace sdl
{

/**
 * Constructor initilizes members and SDL, TTF
 */

Application::Application()
{
    m_aCore = NULL;
    m_gCore = NULL;
    m_gScreen = NULL;
    m_running = true;
	m_framesPerSecond = 0;
}

Application::~Application()
{
    delete m_gCore;
    delete m_gScreen;
    delete m_aCore;
    //close subsystems
    TTF_Quit( );
    SDL_Quit( );
}

/**
 * Returns whether the application is still running
 */

bool Application::GetRunning()
{
    return m_running;
}

/**
 * Initializes the application. Derived classes can override this method but
 * they need to call it first in order to initilize the screen.
 *
 * @param
 * - screenW: screen's width
 * - screenH: screen's height
 * - bpp: bits per pixel, screen's depth
 * - fullscreen: flag indicating if the screen should be created fullscreen
 */

bool Application::Init(int screenW, int screenH, int bpp, bool fullscreen)
{
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) return false; //initialize SDL systems

    if( TTF_Init( ) == -1 ) return false; //initialize SDL TTF

    try
    {
        m_gCore = new GraphicsCore;

        //allocate a new screen
        m_gCore->Initialize( screenW, screenH, bpp, fullscreen, true );

        m_gScreen = new gui::Screen( m_gCore->GetSdlScreen( ) );
        
        m_aCore = new al::AudioCore;
        
        m_aCore->Initialize();
    }
    catch( sdl::Exception &exc )
    {
        LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_ERROR ) << exc.Message( );
        return false;
    }

    SDL_ShowCursor( 1 ); //hide OS's cursor

    return true;
}

/**
 * Runs the application. Returns an exit code to main.
 */

int Application::Run()
{
    SDL_Event evt;

    while( GetRunning( ) )
    {
        while( SDL_PollEvent( &evt ) )
        {
            if( evt.type == SDL_QUIT )
            {
                this->Exit( );
            }
        }
    }

    return 0;
}

/**
 * Exits application
 */

void Application::Exit()
{
    m_running = false;
}


/**
 * @return A pointer to the Application's GraphicsCore
 */

GraphicsCore *Application::GetGraphicsCore()
{
    return m_gCore;
}


/**
 * @return A pointer to the application's gui screen.
 */

gui::Screen* Application::GetGuiScreen()
{
    return m_gScreen;
}


};
